﻿#include "FingerprintCacheDB.h"
#include "ZKFingerReader/libs/include/libzkfp.h"
#include <QDebug>

namespace ZKFP
{

QString BlobToBase64(QByteArray regTemplate)
{
    int size = (regTemplate.size() * 8 + 5 )/ 6;
    char * str = new char[size + 1];
    memset(str, 0, size + 1);
    ZKFPM_BlobToBase64(reinterpret_cast<unsigned char *>(regTemplate.data()), regTemplate.size(),
                       str, size + 1);
    QString ret(str);

//    QString ret2 = regTemplate.toBase64();
//    if(ret == ret2)
//    {
//        qDebug() << "base64 is same";
//    }
    delete []str;
    return ret;
}

QByteArray Base64ToBlob(QString base64String)
{
    int size = base64String.size() * 6 / 8;
    unsigned char *blob = new unsigned char[size];
    int length = ZKFPM_Base64ToBlob(reinterpret_cast<char *> (base64String.data()), blob, size);
    QByteArray ret(reinterpret_cast<char*> (blob), length);
    delete [] blob;
    return ret;
}

FingerprintCacheDB::FingerprintCacheDB(QObject *parent)
    :QObject(parent),
      m_hDBCache(0)
{
    m_hDBCache = ZKFPM_DBInit();
}

FingerprintCacheDB::~FingerprintCacheDB()
{
    ZKFPM_DBFree(m_hDBCache);
}

int FingerprintCacheDB::clearAll()
{
    return ZKFPM_DBClear(m_hDBCache);
}

int FingerprintCacheDB::addItem(unsigned int fingerID, QString base64String)
{
    QByteArray blob = Base64ToBlob(base64String);
    return addItem(fingerID, blob);
}

int FingerprintCacheDB::addItem(unsigned int fingerID, QByteArray regTemplate)
{
    return ZKFPM_DBAdd(m_hDBCache, fingerID, reinterpret_cast<unsigned char *> (regTemplate.data()), regTemplate.size());
}

int FingerprintCacheDB::deleteItem(unsigned int fingerID)
{
    return ZKFPM_DBDel(m_hDBCache, fingerID);
}

int FingerprintCacheDB::count() const
{
    if(m_hDBCache)
    {
        int c;
        ZKFPM_DBCount(m_hDBCache, reinterpret_cast<unsigned int*> (&c));
        return c;
    }
    return 0;
}

int FingerprintCacheDB::verifyFinger(QByteArray regTemplate, QByteArray verTemplate)
{
    if(m_hDBCache)
    {
        int score = ZKFPM_DBMatch(m_hDBCache,
                                  reinterpret_cast<unsigned char *> (regTemplate.data()), regTemplate.size(),
                                  reinterpret_cast<unsigned char *> (verTemplate.data()), verTemplate.size());
        return score;
    }
    return -1;
}

int FingerprintCacheDB::mergeFinger(QByteArray in1, QByteArray in2, QByteArray in3, QByteArray &outTemplate)
{
    if(m_hDBCache)
    {
        unsigned int cbRegTemp = MAX_TEMPLATE_SIZE;
        outTemplate.resize(MAX_TEMPLATE_SIZE);
        outTemplate.fill(0);
        int ret = ZKFPM_DBMerge(m_hDBCache,
                                reinterpret_cast<unsigned char *> (in1.data()),
                                reinterpret_cast<unsigned char *> (in2.data()),
                                reinterpret_cast<unsigned char *> (in3.data()),
                                reinterpret_cast<unsigned char *> (outTemplate.data()), &cbRegTemp);
        outTemplate.resize(cbRegTemp);
        return ret;
    }
    return -1;
}

int FingerprintCacheDB::identify(QString base64String, unsigned int &fingerID, unsigned int &score)
{
    QByteArray fpTemp = Base64ToBlob(base64String);
    return identify(fpTemp, fingerID, score);
}

int FingerprintCacheDB::identify(QByteArray inTemplate, unsigned int &fingerID, unsigned int &score)
{
    return ZKFPM_DBIdentify(m_hDBCache,
                     reinterpret_cast<unsigned char *> (inTemplate.data()), inTemplate.size(),
                     &fingerID, &score);
}

}
